home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / bump.exe / BUMP.CPP < prev    next >
C/C++ Source or Header  |  1992-02-10  |  17KB  |  753 lines

  1. /*               Function definitions for
  2.                        BUMP 1.1
  3.         the Beginners Understandable Matrix Package
  4.                     for Borland C++
  5. */
  6. #include <iostream.h>    // for cout
  7. #include <ctype.h>        // for isdigit()
  8. #include <stdio.h>        // for fgets()
  9. #include <alloc.h>        // for coreleft()
  10. #include <stdlib.h>        // for atof()
  11. #include <conio.h>        // for cprintf()
  12. #include <string.h>        // for strlen()
  13. #include "bump.h"
  14. extern unsigned _stklen = 64000;
  15. int vcount = 0;
  16. ///////////////// The Vector member functions  /////////////////////////
  17.  
  18. Vector::Vector(int anr, int anc, char atemp, int afr, int afc)
  19. {
  20.     if(anr != 1 && anc != 1){
  21.         cout << "Either the number of rows or the number of columns must be 1.\n";
  22.         return;
  23.         }
  24.     which = vcount++;
  25.     nr = anr;
  26.     nc = anc;
  27.     temp = atemp;
  28.     fr = afr;
  29.     fc = afc;
  30.     lr = fr + nr - 1;
  31.     lc = fc + nc - 1;
  32.     nelem = nr + nc - 1;
  33.     if(nelem < 0 || nelem > 16000){
  34.         cout << nelem << "is an illegal number of elements for a vector.\n";
  35.         return;
  36.         }
  37.     if(nelem == 0) 
  38.         v = 0;
  39.     else if((v = new float[nelem]) == 0)
  40.         cout << "Out of memory.\n";
  41.     }
  42. Vector::Vector(Vector& a)
  43. {
  44.     int i;
  45.  
  46.     which = vcount++;
  47.     nr = a.nr;
  48.     nc = a.nc;
  49.     temp = a.temp;
  50.     fr = a.fr;
  51.     fc = a.fc;
  52.     lr = a.lr;
  53.     lc = a.lc;
  54.     nelem = a.nelem;
  55.     /* Before the "operator " functions return, they must "destroy" the Temp
  56.     vector they created.  But since many are returning Temp, C++ calls this
  57.     function to make a copy of Temp.  That call is implicit; the programmer
  58.     does not explicitly do it.  After that call, the destructor is called,
  59.     also implicitly, to destroy the original Temp.  This copy will then be
  60.     returned.  The following device detects that the vector being copied is a
  61.     temporary vector doomed to immediate destruction, so it just captures the
  62.     v array as its own and sets a.v = 0, so that the destructor won't hurt
  63.     it.  */
  64.     
  65.     if(a.temp == 'y'){
  66.         v = a.v;
  67.         a.v = 0;
  68.         }
  69.     else{
  70.         if((v = new float[nelem]) == 0){
  71.             cout << "Out of memory trying to create vector" << which <<".\n";
  72.             exit(1);
  73.             }
  74.         for(i = 0; i < nelem; i++)
  75.             v[i] = a.v[i];
  76.         }
  77.     }
  78. Vector::~Vector()
  79. {
  80.     if(v != 0 ) delete v; 
  81.     }
  82. // Free heap memory
  83. void Vector::freeh()
  84. {
  85.     if(v != 0 ) delete v; 
  86.     v = 0;
  87.     }
  88. int Vector::ReadA(char *filename)
  89. {
  90.     FILE *fp;
  91.     int i,j,k;
  92.     char s[241],field[30];
  93.  
  94.     if((fp = fopen(filename,"rt")) == 0){
  95.         cerr << "Cannot open " << filename << ".\n";
  96.         return(ERR);
  97.         }
  98.     fgets(s,240,fp);
  99.     j = 0;
  100.     for(i = 0; i < nelem; i++){
  101.         if(getfloat(v[i],fp,s,j) == ERR){
  102.             cerr << "Out of data in " << filename << ".\n";
  103.             break;
  104.             }
  105.         }
  106.     fclose(fp);
  107.     return(OK);
  108.     }
  109. void Vector::Display(char *title,int width, int decimalPlaces)
  110. {
  111.     int i, nperline;
  112.     char fmt[20];
  113.  
  114.     if(strlen(title) > 0) printf("\n%s\n", title);
  115.  
  116.     nperline = 79/width;
  117.     sprintf(fmt,"%s%d.%df", "%",width,decimalPlaces);
  118.  
  119.     for(i = 0;i<nelem;i++){
  120.         printf(fmt,v[i]);
  121.         if(i % nperline == nperline - 1) printf("\n");
  122.         }
  123.     }
  124.  
  125. Vector& Vector::operator = (Vector& a)
  126. {
  127.     int i;
  128.     int s = (nelem < a.nelem) ? nelem : a.nelem;
  129.  
  130.     for(i = 0; i < s; i++){
  131.         v[i] = a.v[i];
  132.         }
  133.     a.freet();
  134.     return(*this);
  135.     }
  136. Vector Vector::operator ~ () // Transposition
  137. {
  138.     int i;
  139.     Vector Temp(nc,nr,'y',fc,fr);
  140.     for(i = 0; i < nelem; i++)
  141.         Temp.v[i] = v[i];
  142.     return(Temp);
  143.     }
  144. float& Vector::operator [](int i)
  145. {
  146.  
  147.     if(v==0){
  148.         cerr << "Error: Reference to a deleted vector.\n";
  149.         exit(1);
  150.         }
  151.     if(nc == 1){
  152.         if (fr > i || lr < i){
  153.             cerr << "Illegal vector index: " << i << "\n";
  154.             exit(1);
  155.             }
  156.         return(v[i - fr]);
  157.         }
  158.     else{
  159.         if (fc > i || lc < i){
  160.             cerr << "illegal vector index: " << i << "\n";
  161.             exit(1);
  162.             }
  163.         return(v[i -fc]);
  164.         }
  165.     }
  166. Vector Vector::operator - (Vector &a)
  167. {
  168.     int i;
  169.     if(fr != a.fr || lr != a.lr){
  170.         cout << "vector dimensions do not match in + operator.\n";
  171.         }
  172.  
  173.     Vector Temp(nr,nc,'y');
  174.     for(i = 0; i < nelem; i++)
  175.         Temp.v[i] = v[i] - a.v[i];
  176.     freet();
  177.     return (Temp);
  178.     }
  179. //////////////// Friends of Vector (only) /////////////////////////
  180. /* operator + and operator - are written differently to illustrate
  181.    the two methods.
  182. */
  183. Vector operator + (Vector &a, Vector &b)
  184. {
  185.     int i;
  186.     if(b.fr != a.fr || b.lr != a.lr){
  187.         cout << "vector dimensions do not match in + operator.\n";
  188.         }
  189.  
  190.     Vector Temp(a.nr,a.nc,'y');
  191.     for(i = 0; i < a.nelem; i++)
  192.         Temp.v[i] = a.v[i] + b.v[i];
  193.     a.freet();
  194.     b.freet();
  195.     return (Temp);
  196.     }
  197. Vector operator * (float a, Vector &b)
  198. {
  199.     int i;
  200.     
  201.     Vector Temp(b.nr,b.nc,'y');
  202.     for(i = 0; i < b.nelem; i++)
  203.         Temp.v[i] = a * b.v[i];
  204.     b.freet();
  205.     return (Temp);
  206.     }
  207. Vector operator / (Vector &a, float b)
  208. {
  209.     int i;
  210.     float recip;
  211.     
  212.     Vector Temp(a.nr,a.nc,'y');
  213.     recip = 0;
  214.     if(b == 0)    printf("Division by zero in Vector operator /.\n");
  215.     else recip = 1./b;
  216.     for(i = 0; i < a.nelem; i++)
  217.         Temp.v[i] = a.v[i]*recip;
  218.  
  219.     a.freet();
  220.     return (Temp);
  221.     }
  222. //////////////////////  THE MATRIX MEMBER FUNCTIONS /////////////////////////
  223. Matrix::Matrix(int anr, int anc, char atemp, int afr, int afc)
  224. {
  225.     int i;
  226.  
  227.     which = vcount++;
  228.     nr = anr;
  229.     nc = anc;
  230.     temp = atemp;
  231.     fr = afr;
  232.     fc = afc;
  233.     lr = fr + nr - 1;
  234.     lc = fc + nc - 1;
  235.     if((m = new float* [nr]) == 0) goto gripe;
  236.     m -= fr;
  237.     for(i = fr; i <= lr; i++){
  238.         if((m[i] = new float [nc]) == 0) goto gripe;
  239.         m[i] -= fc;
  240.         }
  241.     return;
  242.     gripe:
  243.         cout << "Out of memory on array number " << which << ".\n";
  244.         exit(1);
  245.     }
  246. Matrix::Matrix(Matrix& a)
  247. {
  248.     int i,j;
  249.     which = vcount++;
  250.     nr = a.nr;
  251.     nc = a.nc;
  252.     temp = a.temp;
  253.     fr = a.fr;
  254.     fc = a.fc;
  255.     lr = a.lr;
  256.     lc = a.lc;
  257.     // See the note at this point in Vector::Vector(Vector& a), which
  258.     // applies here also. 
  259.     if(a.temp == 'y'){
  260.         m = a.m;
  261.         a.m = 0;
  262.         }
  263.     else{
  264.         if((m = new float* [nr]) == 0) goto gripe;
  265.         m -= fr;
  266.         for(i = fr; i <= lr; i++){
  267.             if((m[i] = new float [nc]) == 0) goto gripe;
  268.             m[i] -= fc;
  269.             }
  270.         for(i = fr; i <= lr; i++){
  271.             for(j = fc; j <= lc; j++)
  272.                 m[i][j] = a.m[i][j];
  273.             }
  274.         }
  275.     return;
  276.     gripe:
  277.         cout << "Out of memory on array number " << which << ".\n";
  278.         exit(1);
  279.     }
  280. Matrix::~Matrix()
  281. {
  282.     freeh();
  283.     }
  284. void Matrix::freeh()
  285. {
  286.     int i;
  287.  
  288.     if(m == 0) return;
  289.     for(i = fr; i <= lr; i++)
  290.         delete m[i];
  291.     delete m;
  292.     m = 0;
  293.     }
  294.  
  295. int Matrix::ReadA(char *filename)
  296. {
  297.     FILE *fp;
  298.     int i,j,k;
  299.     char s[241];
  300.  
  301.     if((fp = fopen(filename,"rt")) == 0){
  302.         cerr << "Cannot open " << filename << ".\n";
  303.         return(ERR);
  304.         }
  305.     fgets(s,240,fp);
  306.     k = 0;
  307.     for(i = fr; i <= lr; i++){
  308.         for(j = fc; j <= lc; j++){
  309.             if(getfloat(m[i][j],fp,s,k) == ERR)    break;
  310.             }
  311.         }
  312.     fclose(fp);
  313.     return(OK);
  314.     }
  315. void Matrix::Display(char *title,int width, int decimalPlaces)
  316. {
  317.     int i, j, nperline;
  318.     char fmt[20];
  319.  
  320.     if(strlen(title) > 0) printf("\n%s\n", title);
  321.  
  322.     nperline = 79/width;
  323.     sprintf(fmt,"%s%d.%df", "%",width,decimalPlaces);
  324.     for(i = fr; i <= lr; i++){
  325.         for(j = fc; j <= lc; j++){    
  326.             printf(fmt,m[i][j]);
  327.             if((j - fc % nperline == nperline -1) && j < lc)
  328.                 printf("\n");
  329.             }
  330.         printf("\n");
  331.         }
  332.     }
  333. Matrix& Matrix::operator = (Matrix& a)
  334. {
  335.     int i,j,nrmin,ncmin;
  336.     nrmin = nr < a.nr ? nr : a.nr;
  337.     ncmin = nc < a.nc ? nc : a.nc;
  338.  
  339.     if(nr != a.nr || nc != a.nc)
  340.         cout << "Equating matrices of unequal size.\n";
  341.     for(i = 0; i < nrmin; i++){
  342.         for(j = 0; j < ncmin; j++)
  343.             m[fr+i][fc+j] = a.m[a.fr+i][a.fc+j];
  344.         }
  345.     a.freet();
  346.     return(*this);
  347.     }
  348. Matrix Matrix::operator ~ () //Transposition
  349. {
  350.     int i,j;
  351.  
  352.     Matrix Temp(nc,nr,'y',fc,fr);
  353.     for(i = fr; i <= lr; i++){
  354.         for(j = fc; j <= lc; j++)
  355.             Temp.m[j][i] = m[i][j];
  356.         }
  357.     return(Temp);
  358.     }        
  359. float * Matrix::operator [](int i)
  360. {
  361.     if(m==0){
  362.         cerr << "Error: Reference to a deleted matrix.\n";
  363.         exit(1);
  364.         }
  365.  
  366.     if(i < fr || i > lr ){
  367.         cerr << "illegal matrix row index: " << i << "." << "\n";
  368.         cerr << "returning first row. \n";
  369.         return m[fr];
  370.         }
  371.     return(m[i]);
  372.     }
  373. Matrix Matrix::operator ! () // Inversion
  374. {
  375.     double determinant;
  376.  
  377.     if(temp == 'n'){
  378.         Matrix Temp(*this);
  379.         Temp.temp = 'y';
  380.         Temp.invert();
  381.         return(Temp);
  382.         }
  383.     else{ // If this matrix is temporary, turn i